package com.copy.mapping;

import com.copy.exception.FliedMappingException;
import com.copy.exception.MethodMappingException;
import com.copy.mark.CloneType;
import com.copy.mark.Null;
import com.copy.mark.ParamMap;
import com.copy.mark.ParamMaps;
import com.copy.parse.ParseAnnotationMetaDataStrategyHandler;
import com.copy.parse.transform.TypeTransform;
import com.copy.pojo.BeanMethod;
import com.copy.pojo.Property;
import com.copy.scan.ScanBasePackageStrategy;
import java.lang.reflect.Method;

/**
 * author: liziyun
 * date: 2019-9-30
 * email: root@ofo.email
 * describe: 属性映射解析器.
 *        A实例化对象某属性 和 B实例化对戏那个某属性,映射关系.
 *
 */
public abstract class PropertyMappingHandler extends ParseAnnotationMetaDataStrategyHandler implements PropertyMappingStrategy {

    public PropertyMappingHandler(ScanBasePackageStrategy scanBasePackageStrategy) {
        super(scanBasePackageStrategy);
    }

    @Override
    public void getMethodMetadaByAuto(BeanMethod beanMethod) throws RuntimeException {
        System.out.println(beanMethod.isEagerInstance());
        //解析方法名
        Method method = beanMethod.getMethod();
        String methodName = method.getName();
        Class<?> targetBeanClass=null;
        Class<?> resurceBeanClass=null;
        try {
            targetBeanClass= method.getReturnType();
            resurceBeanClass = method.getParameterTypes()[0];
        }catch (Exception e){
            throw new MethodMappingException(methodName,"参数");
        }

        String[] ands = methodName.split("And");
        for (String and : ands) {
            String[] by = and.split("By");
                String targetProperty=null;
            String resourceProperty=null;
                try {
                    targetProperty = toLower(by[0]);
                    resourceProperty = toLower(by[1]);
                }catch (Exception e){
                    throw new MethodMappingException(methodName,"方法名");
                }
                Property property = new Property(targetProperty, resourceProperty);
                beanMethod.setPropertyMapping(targetProperty,property);
        }
    }

    @Override
    public void getMethodMetadaByParamMaps(BeanMethod beanMethod)throws RuntimeException {
        Method method = beanMethod.getMethod();
        Class<?>[] parameterTypes = method.getParameterTypes();
        ParamMaps params = method.getAnnotation(ParamMaps.class);
        ParamMap[] entrys = params.value();
        for (ParamMap entry : entrys) {
            String targetPropertyName = entry.targetProperty();
            String resourcePropertyName = entry.resourceProperty();
            //设置targetPropertyName 和 resourcePropertyName
            Property property = new Property(targetPropertyName,resourcePropertyName );
            //尝试获取类型转换器
            Class typeTransformClass = entry.TYPE_TRANSFORM();//全限定类名
            if (typeTransformClass!= Null.class){//存在转换器
                if (typeTransformClass.getInterfaces()[0]==TypeTransform.class){
                    property.setTypeTransform(typeTransformClass);
                }else{
                    throw new RuntimeException(method.getName()+"()方法 "+",属性"+targetPropertyName+"的类型转换器未实现TypeTransform接口");
                }
            }
            //尝试获取拷贝类型
            CloneType propertyCloneType = entry.CLONE_TYPE();
            CloneType methodCloneType = params.CLONE_TYPE();
            //尝试获取BigDecimal
            if (entry.isBigDecimal()){
                property.setBigDecimal(true);
                property.setOpenForceCast(true);
            }
            //尝试获取强制转换
            if (entry.openForceCast()){
                property.setOpenForceCast(true);
            }
            //设置克隆方式： 属性局部优先级 》 方法全局优先级
            if (propertyCloneType==CloneType.NULL){//属性中没有，采用全局拷贝类型
                //尝试使用方法全局克隆
                if (methodCloneType==CloneType.NULL){
                    //默认使用浅克隆
                    property.setCloneType(CloneType.NotDeepClone);
                }else{
                    property.setCloneType(methodCloneType);
                }

            }else{//属性中存在拷贝类型，忽略全局拷贝类型
                property.setCloneType(propertyCloneType);
            }
            //Property对象添加到BeanMethod中
            beanMethod.setPropertyMapping(targetPropertyName,property);
        }
    }
    public void getMethodMetadaByClone(BeanMethod beanMethod){
        //空实现,后期扩展
    }
    //首字母大写变小写
    public static String toLower(String str){
        char c = str.charAt(0);
        if (65<= c &&c<=90){
            String substring = str.substring(1);
            c=(char) ((int)c+32);
            return  c+substring;
        }
        return  str;
    }

}
